/* 示例：>>>>>>>>>>
file: 传入的 file.file
num: 压缩次数
numberOfCycles: 默认压缩次数

const fileCompressionUpload = (file, num = 1) => {
    const formData = new FormData();
    transformFile(file, {
      compressThreshold: 0.1, // 压缩的阈值,图片大小超过100kb,则需要进行压缩
      isPictureCompress: true, // 是否开启图片压缩
      pictureQuality: 0.52, // 指定压缩的图片质量,取值范围为0~1,quality值越小,图像越模糊,默认图片质量为 0.92
    })
      .then((compressedFile) => {
        formData.append('file', compressedFile, compressedFile.name);
        // console.log(URL.createObjectURL(compressedFile), '>>>>>>>>>>> res');
        // console.log(URL.createObjectURL(file.file), '>>>>>>>>>>> file.file');
        if (num < numberOfCycles) {
          num++;
          fileCompressionUpload(compressedFile, num);
          return;
        }
        console.log(compressedFile, '压缩后的结果: =======>', compressedFile.size);
        getFile(formData, file); // 调用文件上传接口
      });
  };
*/
// 文件上传压缩
export const transformFile = (file = {}, compressionParams = {}) => {
  console.log('压缩文件：', file);
  // 将blob转换为file
  const blobToFile = (theBlob) => {
    theBlob.lastModifiedDate = new Date();
    theBlob.lastModified = +new Date();
    theBlob.name = file.fileName || file.name || '';
    theBlob.webkitRelativePath = file?.webkitRelativePath || '';
    return theBlob;
  };
  const checkIsImage = (fileName) => {
    const imgType = fileName.split('.');
    let isImg = false;
    try {
      if (!Array.isArray(imgType)) {
        throw new Error('Unexpected: \'imgType\' is not an array');
      }
      if (imgType[1].search(/png|jpeg|jpg/img) > -1) {
        isImg = true;
      }
    } catch (err) {
      console.error(err);
    }
    return isImg;
  };
  /**
   * 针对图片进行压缩,如果图片大小超过压缩阈值,则执行压缩,否则不压缩
   */
  // 判断是否是图片类型
  if (checkIsImage(file.name)) {
    const {
      compressThreshold = 1, // 压缩的阈值,图片大小超过1M,则需要进行压缩
      isPictureCompress = false, // 是否开启图片压缩
      pictureQuality = 0.92, // 指定压缩的图片质量,取值范围为0~1,quality值越小,图像越模糊,默认图片质量为0.92
    } = compressionParams;
    const fileSize = file.size / 1024 / 1024;
    console.info(`原图大小: ${fileSize}M---${fileSize >= compressThreshold ? '超过' : '不超过'}${compressThreshold}M,
    ${(fileSize >= compressThreshold && isPictureCompress) ? '' : '不'}开启图片压缩，压缩质量为：${pictureQuality}，该值越小，图像越模糊`);
    // 当开启图片压缩且图片大小大于等于压缩阈值,进行压缩
    if ((fileSize >= compressThreshold) && isPictureCompress) {
      // 判断浏览器内核是否支持base64图片压缩
      if (typeof (FileReader) === 'undefined') {
        return file;
      }
      try {
        // 需要一个 loading
        return new Promise((resolve) => {
          // 声明FileReader文件读取对象
          const reader = new FileReader();
          reader.readAsDataURL(file);
          reader.onload = () => {
            // 生成canvas画布
            const canvas = document.createElement('canvas');
            // 生成img
            const img = document.createElement('img');
            img.src = reader.result;
            img.onload = () => {
              const ctx = canvas.getContext('2d');
              // 原始图片宽度、高度
              const originImageWidth = img.width;
              const originImageHeight = img.height;
              // 默认最大尺度的尺寸限制在（1920 * 1080）
              const maxWidth = 1920;
              const maxHeight = 1080;
              const ratio = maxWidth / maxHeight;
              // 目标尺寸
              let targetWidth = originImageWidth;
              let targetHeight = originImageHeight;
              // 当图片的宽度或者高度大于指定的最大宽度或者最大高度时,进行缩放图片
              if (originImageWidth > maxWidth || originImageHeight > maxHeight) {
                // 超过最大宽高比例
                if ((originImageWidth / originImageHeight) > ratio) {
                  // 宽度取最大宽度值maxWidth,缩放高度
                  targetWidth = maxWidth;
                  targetHeight = Math.round(maxWidth * (originImageHeight / originImageWidth));
                } else {
                  // 高度取最大高度值maxHeight,缩放宽度
                  targetHeight = maxHeight;
                  targetWidth = Math.round(maxHeight * (originImageWidth / originImageHeight));
                }
              }
              // canvas对图片进行缩放
              canvas.width = targetWidth;
              canvas.height = targetHeight;
              // 清除画布
              ctx.clearRect(0, 0, targetWidth, targetHeight);
              // 绘制图片
              ctx.drawImage(img, 0, 0, targetWidth, targetHeight);
              // quality值越小,图像越模糊,默认图片质量为0.92
              const imageDataURL = canvas.toDataURL(file.type || 'image/jpeg', pictureQuality);
              // 去掉URL的头,并转换为byte
              const imageBytes = window.atob(imageDataURL.split(',')[1]);
              const mimeType = imageDataURL.split(',')[0].match(/:(.*?);/)[1];
              // 处理异常,将ascii码小于0的转换为大于0
              const arrayBuffer = new ArrayBuffer(imageBytes.length);
              const uint8Array = new Uint8Array(arrayBuffer);
              for (let i = 0; i < imageBytes.length; i++) {
                uint8Array[i] = imageBytes.charCodeAt(i);
              }
              const blob = new Blob([arrayBuffer], { type: mimeType || 'image/jpeg' });
              const blobFile = blobToFile(blob);
              // const mimeType = imageDataURL.split(',')[0].match(/:(.*?);/)[1];
              // const newFile = new File([blobFile], file.name, { type: mimeType || 'image/jpeg' });
              // const newFile = new File([uint8Array], file.name, { type: mimeType || 'image/jpeg' });
              // console.log('after compress, the file size is : ', (newFile.size / 1024 / 1024) + "M");
              resolve(blobFile);
            };
          };
          reader.onerror = () => {
            // 需要一个 loading
            return file;
          };
        })
          .then((res) => {
            // 需要一个 loading
            return res;
          })
          .catch(() => {
            // 需要一个 loading
            return file;
          });
      } catch (e) {
        // 需要一个 loading
        // 压缩出错,直接返回原file对象
        return file;
      }
    } else {
      // 不需要压缩，直接返回原file对象
      return new Promise((resolve) => {
        return resolve(file);
      });
    }
  } else {
    // 非图片文件,不进行压缩,直接返回原file对象
    return new Promise((resolve) => {
      return resolve(file);
    });
  }
};
